C2P(netif_fe_interface_status_changed_t, handle, Int, Long);
C2P(netif_fe_interface_status_changed_t, status, Int, Long);
C2P(netif_fe_interface_status_changed_t, evtchn, Int, Long);
+ C2P(netif_fe_interface_status_changed_t, mac[0], Int, Long);
+ C2P(netif_fe_interface_status_changed_t, mac[1], Int, Long);
+ C2P(netif_fe_interface_status_changed_t, mac[2], Int, Long);
+ C2P(netif_fe_interface_status_changed_t, mac[3], Int, Long);
+ C2P(netif_fe_interface_status_changed_t, mac[4], Int, Long);
+ C2P(netif_fe_interface_status_changed_t, mac[5], Int, Long);
return dict;
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_DRIVER_STATUS_CHANGED):
C2P(netif_fe_driver_status_changed_t, status, Int, Long);
@param index: vif index
@return: deferred
"""
- if vm.netif_backend:
- raise VmError('vif: vif in netif backend domain')
+ #if vm.netif_backend:
+ # raise VmError('vif: vif in netif backend domain')
vif = vm.next_device_index('vif')
vmac = sxp.child_value(val, "mac")
backend = vm.get_device_backend('vif')
@param index: vbd index
@return: deferred
"""
- if vm.blkif_backend:
- raise VmError('vbd: vbd in blkif backend domain')
+ #if vm.blkif_backend:
+ # raise VmError('vbd: vbd in blkif backend domain')
uname = sxp.child_value(val, 'uname')
if not uname:
raise VmError('vbd: Missing uname')
fn = FormFn(self.xd.domain_shutdown,
[['dom', 'str'],
['reason', 'str']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
req.setResponseCode(http.ACCEPTED)
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
fn = FormFn(self.xd.domain_destroy,
[['dom', 'str'],
['reason', 'str']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
req.setHeader("Location", "%s/.." % req.prePathURL())
return val
fn = FormFn(self.xd.domain_save,
[['dom', 'str'],
['file', 'str']])
- deferred = fn(req.args, {'dom': self.dom.name})
+ deferred = fn(req.args, {'dom': self.dom.id})
deferred.addCallback(self._op_save_cb, req)
deferred.addErrback(self._op_save_err, req)
return deferred
fn = FormFn(self.xd.domain_migrate,
[['dom', 'str'],
['destination', 'str']])
- deferred = fn(req.args, {'dom': self.dom.name})
+ deferred = fn(req.args, {'dom': self.dom.id})
print 'op_migrate>', deferred
deferred.addCallback(self._op_migrate_cb, req)
deferred.addErrback(self._op_migrate_err, req)
fn = FormFn(self.xd.domain_pincpu,
[['dom', 'str'],
['cpu', 'int']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
return val
def op_cpu_bvt_set(self, op, req):
['warpvalue', 'int'],
['warpl', 'long'],
['warpu', 'long']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
return val
def op_cpu_fbvt_set(self, op, req):
['warp', 'int'],
['warpl', 'int'],
['warpu', 'int']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
return val
def op_cpu_atropos_set(self, op, req):
['slice', 'int'],
['latency', 'int'],
['xtratime', 'int']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
return val
def op_maxmem_set(self, op, req):
fn = FormFn(self.xd.domain_maxmem_set,
[['dom', 'str'],
['memory', 'int']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
return val
def op_device_create(self, op, req):
fn = FormFn(self.xd.domain_device_create,
[['dom', 'str'],
['config', 'sxpr']])
- d = fn(req.args, {'dom': self.dom.name})
+ d = fn(req.args, {'dom': self.dom.id})
return d
def op_device_destroy(self, op, req):
[['dom', 'str'],
['type', 'str'],
['idx', 'str']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
return val
def op_vifs(self, op, req):
- devs = self.xd.domain_vif_ls(self.dom.name)
+ devs = self.xd.domain_vif_ls(self.dom.id)
return [ dev.sxpr() for dev in devs ]
def op_vif(self, op, req):
fn = FormFn(self.xd.domain_vif_get,
[['dom', 'str'],
['vif', 'str']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
return val
def op_vbds(self, op, req):
- devs = self.xd.domain_vbd_ls(self.dom.name)
+ devs = self.xd.domain_vbd_ls(self.dom.id)
return [ dev.sxpr() for dev in devs ]
def op_vbd(self, op, req):
fn = FormFn(self.xd.domain_vbd_get,
[['dom', 'str'],
['vbd', 'str']])
- val = fn(req.args, {'dom': self.dom.name})
+ val = fn(req.args, {'dom': self.dom.id})
return val
def render_POST(self, req):
self.addMethod(CMSG_BLKIF_BE,
CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED,
self.recv_be_driver_status_changed)
- self.attached = 1
self.registerChannel()
-
- def respond_be_create(self, msg, d):
- """Response handler for a be_create message.
- Calls I{d} with the block interface created.
-
- @param msg: message
- @type msg: xu message
- @param d: deferred to call
- @type d: Deferred
- """
- val = unpackMsg('blkif_be_create_t', msg)
- blkif = self.factory.getInstanceByDom(val['domid'])
- d.callback(blkif)
-
- def respond_be_connect(self, msg):
- """Response handler for a be_connect message.
-
- @param msg: message
- @type msg: xu message
- """
- val = unpackMsg('blkif_be_connect_t', msg)
- blkif = self.factory.getInstanceByDom(val['domid'])
- if blkif:
- blkif.send_fe_interface_status_changed()
- else:
- pass
-
- def respond_be_vbd_create(self, msg, dev, d):
- """Response handler for a be_vbd_create message.
- Tries to grow the vbd, and passes the deferred I{d} on for
- the grow to call.
-
- @param msg: message
- @type msg: xu message
- @param dev: device
- @type dev: BlkDev
- @param d: deferred to call
- @type d: Deferred
- """
- val = unpackMsg('blkif_be_vbd_create_t', msg)
- blkif = self.factory.getInstanceByDom(val['domid'])
- if blkif:
- d1 = defer.Deferred()
- d1.addCallback(self.respond_be_vbd_grow, dev, d)
- if d: d1.addErrback(d.errback)
- blkif.send_be_vbd_grow(val['vdevice'], response=d1)
- else:
- pass
-
- def respond_be_vbd_grow(self, msg, dev, d):
- """Response handler for a be_vbd_grow message.
-
- @param msg: message
- @type msg: xu message
- @param dev: device
- @type dev: BlkDev
- @param d: deferred to call
- @type d: Deferred or None
- """
- val = unpackMsg('blkif_be_vbd_grow_t', msg)
- status = val['status']
- if status != BLKIF_BE_STATUS_OKAY:
- raise XendError("Adding extent to vbd failed: device %x, error %d"
- % (val['extent.device'], status))
- if d:
- d.callback(dev)
def recv_be_driver_status_changed(self, msg, req):
"""Request handler for be_driver_status_changed messages.
"""
val = unpackMsg('blkif_be_driver_status_changed_t', msg)
status = val['status']
- if status == BLKIF_DRIVER_STATUS_UP and not self.attached:
- for blkif in self.factory.getInstances():
- if blkif.backendController == self:
- blkif.detach()
-
class BlkifControllerFactory(controller.SplitControllerFactory):
"""Factory for creating block device interface controllers.
def __init__(self):
controller.SplitControllerFactory.__init__(self)
- self.attached = 1
def createInstance(self, dom, recreate=0, backend=0):
"""Create a block device controller for a domain.
@return: deferred
@rtype: twisted.internet.defer.Deferred
"""
- d = defer.Deferred()
blkif = self.getInstanceByDom(dom)
if blkif:
+ d = defer.Deferred()
d.callback(blkif)
else:
blkif = BlkifController(self, dom, backend)
self.addInstance(blkif)
- if recreate:
- d.callback(blkif)
- else:
- d1 = defer.Deferred()
- d1.addCallback(blkif.backendController.respond_be_create, d)
- d1.addErrback(d.errback)
- blkif.send_be_create(response=d1)
+ d = blkif.connect(recreate=recreate)
return d
def getDomainDevices(self, dom):
@param dom: domain
@type dom: int
@param vdev: device index
- @type vedv: int
+ @type vdev: int
@return: device
@rtype: device
"""
def createBackendController(self, dom):
return BlkifBackendController(self, dom)
- def setControlDomain(self, dom, recreate=0):
- """Set the back-end block device controller domain.
-
- @param dom: domain
- @type dom: int
- @param recreate: if true it's a recreate (after xend restart)
- @type recreate: int
- """
- if self.dom == dom: return
- self.deregisterChannel()
- if not recreate:
- self.attached = 0
- self.dom = dom
- self.registerChannel()
-
- def getControlDomain(self):
- """Get the back-end block device controller domain.
-
- @return: domain
- @rtype: int
- """
- return self.dom
-
- def reattachDevice(self, dom, vdev):
- """Reattach a device (on changing control domain).
-
- @param dom: domain
- @type dom: int
- @param vdev: device index
- @type vdev: int
- """
- blkif = self.getInstanceByDom(dom)
- if blkif:
- blkif.reattachDevice(vdev)
- self.attached = self.devicesAttached()
- if self.attached:
- self.reattached()
-
- def devicesAttached(self):
- """Check if all devices are attached.
-
- @return: true if all devices attached
- @rtype: bool
- """
- attached = 1
- for blkif in self.getInstances():
- if not blkif.attached:
- attached = 0
- break
- return attached
-
- def reattached(self):
- """Notify all block interfaces we have been reattached
- (after changing control domain).
- """
- for blkif in self.getInstances():
- blkif.reattached()
-
-
-
class BlkDev(controller.Dev):
"""Info record for a block device.
"""
self.device = segment['device']
self.start_sector = segment['start_sector']
self.nr_sectors = segment['nr_sectors']
- self.attached = 1
+
+ def getBackendController(self):
+ return self.controller.backendController
def readonly(self):
return 'w' not in self.mode
def destroy(self):
log.debug("Destroying vbd domain=%d vdev=%d", self.controller.dom, self.vdev)
- self.controller.send_be_vbd_destroy(self.vdev)
+ self.send_be_vbd_destroy()
+
+ def attach(self, d):
+ """Attach the device to its controller.
+
+ @param d: deferred to call with the device on success
+ """
+ d1 = defer.Deferred()
+ d1.addCallback(self.respond_be_vbd_create, d)
+ d1.addErrback(d.errback)
+ self.send_be_vbd_create(response=d1)
+
+ def send_be_vbd_create(self, response=None):
+ msg = packMsg('blkif_be_vbd_create_t',
+ { 'domid' : self.controller.dom,
+ 'blkif_handle' : self.controller.handle,
+ 'vdevice' : self.vdev,
+ 'readonly' : self.readonly() })
+ self.getBackendController().writeRequest(msg, response=response)
+
+ def respond_be_vbd_create(self, msg, d):
+ """Response handler for a be_vbd_create message.
+ Tries to grow the vbd.
+
+ @param msg: message
+ @type msg: xu message
+ @param d: deferred to call
+ @type d: Deferred
+ """
+ val = unpackMsg('blkif_be_vbd_create_t', msg)
+ d1 = defer.Deferred()
+ d1.addCallback(self.respond_be_vbd_grow, d)
+ if d: d1.addErrback(d.errback)
+ self.send_be_vbd_grow(response=d1)
+
+ def send_be_vbd_grow(self, response=None):
+ msg = packMsg('blkif_be_vbd_grow_t',
+ { 'domid' : self.controller.dom,
+ 'blkif_handle' : self.controller.handle,
+ 'vdevice' : self.vdev,
+ 'extent.device' : self.device,
+ 'extent.sector_start' : self.start_sector,
+ 'extent.sector_length' : self.nr_sectors })
+ self.getBackendController().writeRequest(msg, response=response)
+
+ def respond_be_vbd_grow(self, msg, d):
+ """Response handler for a be_vbd_grow message.
+
+ @param msg: message
+ @type msg: xu message
+ @param d: deferred to call
+ @type d: Deferred or None
+ """
+ val = unpackMsg('blkif_be_vbd_grow_t', msg)
+ status = val['status']
+ if status != BLKIF_BE_STATUS_OKAY:
+ err = XendError("Adding extent to vbd failed: device %d, error %d"
+ % (self.vdev, status))
+ #if(d):
+ # d.errback(err)
+ raise err
+ if d:
+ d.callback(self)
+
+ def send_be_vbd_destroy(self, response=None):
+ log.debug('>BlkDev>send_be_vbd_destroy> dom=%d vdev=%d',
+ self.controller.dom, self.vdev)
+ msg = packMsg('blkif_be_vbd_destroy_t',
+ { 'domid' : self.controller.dom,
+ 'blkif_handle' : self.controller.handle,
+ 'vdevice' : self.vdev })
+ self.controller.delDevice(self.vdev)
+ self.getBackendController().writeRequest(msg, response=response)
+
class BlkifController(controller.SplitController):
"""Block device interface controller. Handles all block devices
"""
def __init__(self, factory, dom, backend):
+ """Create a block device controller.
+ The controller must be connected using connect() before it can be used.
+ Do not call directly - use createInstance() on the factory instead.
+ """
controller.SplitController.__init__(self, factory, dom, backend)
self.devices = {}
self.addMethod(CMSG_BLKIF_FE,
self.addMethod(CMSG_BLKIF_FE,
CMSG_BLKIF_FE_INTERFACE_CONNECT,
self.recv_fe_interface_connect)
- self.attached = 1
+ self.handle = 0
self.evtchn = None
self.registerChannel()
self.devices[vdev] = dev
return dev
+ def delDevice(self, vdev):
+ if vdev in self.devices:
+ del self.devices[vdev]
+
def attachDevice(self, vdev, mode, segment, recreate=0):
"""Attach a device to the specified interface.
On success the returned deferred will be called with the device.
if recreate:
d.callback(dev)
else:
- d1 = defer.Deferred()
- d1.addCallback(self.backendController.respond_be_vbd_create, dev, d)
- d1.addErrback(d.errback)
- self.send_be_vbd_create(vdev, response=d1)
+ dev.attach(d)
return d
def destroy(self):
- def cb_destroy(val):
- self.send_be_destroy()
+ """Destroy the controller and all devices.
+ """
log.debug("Destroying blkif domain=%d", self.dom)
- d = defer.Deferred()
- d.addCallback(cb_destroy)
- self.send_be_disconnect(response=d)
+ self.destroyDevices()
+ self.disconnect()
def destroyDevices(self):
+ """Destroy all devices.
+ """
for dev in self.getDevices():
dev.destroy()
- def detach(self):
- """Detach all devices, when the back-end control domain has changed.
- """
- self.attached = 0
- for dev in self.devices.values():
- dev.attached = 0
- d1 = defer.Deferred()
- d1.addCallback(self.backendController.respond_be_vbd_create, None, None)
- self.send_be_vbd_create(vdev, response=d1)
-
- def reattachDevice(self, vdev):
- """Reattach a device, when the back-end control domain has changed.
+ def connect(self, recreate=0):
+ """Connect the controller to the blkif control interface.
+
+ @param recreate: true if after xend restart
+ @return: deferred
"""
- dev = self.devices[vdev]
- dev.attached = 1
- attached = 1
- for dev in self.devices.values():
- if not dev.attached:
- attached = 0
- break
- self.attached = attached
- return self.attached
-
- def reattached(self):
- """All devices have been reattached after the back-end control
- domain has changed.
+ log.debug("Connecting blkif domain=%d", self.dom)
+ d = defer.Deferred()
+ if recreate:
+ d.callback(self)
+ else:
+ def cbresp(msg):
+ return self
+ d.addCallback(cbresp)
+ self.send_be_create(response=d)
+ return d
+
+ def send_be_create(self, response=None):
+ msg = packMsg('blkif_be_create_t',
+ { 'domid' : self.dom,
+ 'blkif_handle' : self.handle })
+ self.backendController.writeRequest(msg, response=response)
+
+ def disconnect(self):
+ """Disconnect from the blkif control interface and destroy it.
"""
- msg = packMsg('blkif_fe_interface_status_changed_t',
- { 'handle' : 0,
- 'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED})
- self.writeRequest(msg)
+ def cb_destroy(val):
+ self.send_be_destroy()
+ d = defer.Deferred()
+ d.addCallback(cb_destroy)
+ self.send_be_disconnect(response=d)
+
+ def send_be_disconnect(self, response=None):
+ log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
+ msg = packMsg('blkif_be_disconnect_t',
+ { 'domid' : self.dom,
+ 'blkif_handle' : self.handle })
+ self.backendController.writeRequest(msg, response=response)
+ def send_be_destroy(self, response=None):
+ log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
+ msg = packMsg('blkif_be_destroy_t',
+ { 'domid' : self.dom,
+ 'blkif_handle' : self.handle })
+ self.backendController.writeRequest(msg, response=response)
+
def recv_fe_driver_status_changed(self, msg, req):
msg = packMsg('blkif_fe_interface_status_changed_t',
- { 'handle' : 0,
+ { 'handle' : self.handle,
'status' : BLKIF_INTERFACE_STATUS_DISCONNECTED,
'evtchn' : 0 })
self.writeRequest(msg)
-
+
def recv_fe_interface_connect(self, msg, req):
val = unpackMsg('blkif_fe_interface_connect_t', msg)
self.evtchn = channel.eventChannel(0, self.dom)
'evtchn' : self.evtchn['port1'],
'shmem_frame' : val['shmem_frame'] })
d = defer.Deferred()
- d.addCallback(self.backendController.respond_be_connect)
+ d.addCallback(self.respond_be_connect)
self.backendController.writeRequest(msg, response=d)
+ def respond_be_connect(self, msg):
+ """Response handler for a be_connect message.
+
+ @param msg: message
+ @type msg: xu message
+ """
+ val = unpackMsg('blkif_be_connect_t', msg)
+ self.send_fe_interface_status_changed()
+
def send_fe_interface_status_changed(self, response=None):
msg = packMsg('blkif_fe_interface_status_changed_t',
- { 'handle' : 0,
+ { 'handle' : self.handle,
'status' : BLKIF_INTERFACE_STATUS_CONNECTED,
'evtchn' : self.evtchn['port2'] })
self.writeRequest(msg, response=response)
-
- def send_be_create(self, response=None):
- msg = packMsg('blkif_be_create_t',
- { 'domid' : self.dom,
- 'blkif_handle' : 0 })
- self.backendController.writeRequest(msg, response=response)
-
- def send_be_disconnect(self, response=None):
- log.debug('>BlkifController>send_be_disconnect> dom=%d', self.dom)
- msg = packMsg('blkif_be_disconnect_t',
- { 'domid' : self.dom,
- 'blkif_handle' : 0 })
- self.backendController.writeRequest(msg, response=response)
-
- def send_be_destroy(self, response=None):
- log.debug('>BlkifController>send_be_destroy> dom=%d', self.dom)
- msg = packMsg('blkif_be_destroy_t',
- { 'domid' : self.dom,
- 'blkif_handle' : 0 })
- self.backendController.writeRequest(msg, response=response)
-
- def send_be_vbd_create(self, vdev, response=None):
- dev = self.devices[vdev]
- msg = packMsg('blkif_be_vbd_create_t',
- { 'domid' : self.dom,
- 'blkif_handle' : 0,
- 'vdevice' : dev.vdev,
- 'readonly' : dev.readonly() })
- self.backendController.writeRequest(msg, response=response)
-
- def send_be_vbd_grow(self, vdev, response=None):
- dev = self.devices[vdev]
- msg = packMsg('blkif_be_vbd_grow_t',
- { 'domid' : self.dom,
- 'blkif_handle' : 0,
- 'vdevice' : dev.vdev,
- 'extent.device' : dev.device,
- 'extent.sector_start' : dev.start_sector,
- 'extent.sector_length' : dev.nr_sectors })
- self.backendController.writeRequest(msg, response=response)
-
- def send_be_vbd_destroy(self, vdev, response=None):
- log.debug('>BlkifController>send_be_vbd_destroy> dom=%d vdev=%d', self.dom, vdev)
- dev = self.devices[vdev]
- msg = packMsg('blkif_be_vbd_destroy_t',
- { 'domid' : self.dom,
- 'blkif_handle' : 0,
- 'vdevice' : dev.vdev })
- del self.devices[vdev]
- self.backendController.writeRequest(msg, response=response)
+
(ty, subty) = self.getMessageType(msg)
#todo: Must respond before writing any more messages.
#todo: Should automate this (respond on write)
- self.port.write_response(msg)
+ responded = 0
dev = self.getDevice(ty)
if dev:
- dev.requestReceived(msg, ty, subty)
+ responded = dev.requestReceived(msg, ty, subty)
else:
print ("requestReceived> No device: Message type %s %d:%d"
% (msgTypeName(ty, subty), ty, subty)), self
+ if not responded:
+ self.port.write_response(msg)
def handleResponses(self):
work = 0
if DEBUG:
print 'requestReceived>',
printMsg(msg, all=1)
+ responded = 0
method = self.getMethod(type, subtype)
if method:
- method(msg, 1)
+ responded = method(msg, 1)
elif DEBUG:
print ('requestReceived> No handler: Message type %s %d:%d'
% (msgTypeName(type, subtype), type, subtype)), self
+ return responded
def responseReceived(self, msg, type, subtype):
"""Dispatch a response to handlers.
else:
args[k] = v
msg = xu.message(major, minor, msgid, args)
- if DEBUG: print '<packMsg', msg.get_header()['id'], ty, params
+ if DEBUG: print '<packMsg', msg.get_header()['id'], ty, args
return msg
def unpackMsg(ty, msg):
@rtype: dict
"""
args = msg.get_payload()
+ if DEBUG: print '>unpackMsg', args
if isinstance(args, types.StringType):
- args = { 'value': args }
+ args = {'value': args}
else:
mac = [0, 0, 0, 0, 0, 0]
macs = []
ty = msgTypeName(major, minor)
print >>out, 'message:', 'type=', ty, '%d:%d' % (major, minor), 'id=%d' % msgid
if all:
- print >>out, 'payload=', unpackMsg(ty, msg)
+ print >>out, 'payload=', msg.get_payload()
self.addMethod(CMSG_NETIF_BE,
CMSG_NETIF_BE_DRIVER_STATUS_CHANGED,
self.recv_be_driver_status_changed)
- self.attached = 1
self.registerChannel()
- def respond_be_connect(self, msg):
- val = unpackMsg('netif_be_connect_t', msg)
- dom = val['domid']
- vif = val['netif_handle']
- netif = self.factory.getInstanceByDom(dom)
- if netif:
- netif.send_interface_connected(vif)
- else:
- log.warning("respond_be_connect> unknown vif dom=%d vif=%d", dom, vif)
- pass
-
def recv_be_driver_status_changed(self, msg, req):
val = unpackMsg('netif_be_driver_status_changed_t', msg)
status = val['status']
- if status == NETIF_DRIVER_STATUS_UP and not self.attached:
- # If we are not attached the driver domain was changed, and
- # this signals the new driver domain is ready.
- for netif in self.factory.getInstances():
- if netif.backendController == self:
- netif.reattach_devices()
- self.attached = 1
class NetifControllerFactory(controller.SplitControllerFactory):
"""Factory for creating network interface controllers.
def __init__(self):
controller.ControllerFactory.__init__(self)
- self.attached = 1
def createInstance(self, dom, recreate=0, backend=0):
"""Create or find the network interface controller for a domain.
def createBackendController(self, dom):
return NetifBackendController(self, dom)
- def setControlDomain(self, dom, recreate=0):
- """Set the 'back-end' device driver domain.
-
- @param dom: domain
- @param recreate: if true this is a recreate (xend restarted)
- """
- if self.dom == dom: return
- self.deregisterChannel()
- if not recreate:
- self.attached = 0
- self.dom = dom
- self.registerChannel()
-
- def getControlDomain(self):
- """Get the domain id of the back-end control domain.
-
- @return domain id
- """
- return self.dom
-
class NetDev(controller.Dev):
"""Info record for a network device.
"""
self.evtchn = None
self.configure(config)
+ def getBackendController(self):
+ return self.controller.backendController
+
def configure(self, config):
self.config = config
self.mac = None
if vnet:
vnet.vifctl(op, self.get_vifname(), self.get_mac())
+ def attach(self, d):
+ print 'attach>', d
+ self.send_be_create(response=d)
+
+ def send_be_create(self, response=None):
+ msg = packMsg('netif_be_create_t',
+ { 'domid' : self.controller.dom,
+ 'netif_handle' : self.vif,
+ 'mac' : self.mac })
+ self.getBackendController().writeRequest(msg, response=response)
+
def destroy(self):
"""Destroy the device's resources and disconnect from the back-end
device controller.
"""
def cb_destroy(val):
- self.controller.send_be_destroy(self.vif)
+ self.send_be_destroy()
log.debug("Destroying vif domain=%d vif=%d", self.controller.dom, self.vif)
self.vifctl('down')
d = defer.Deferred()
d.addCallback(cb_destroy)
- self.controller.send_be_disconnect(self.vif, response=d)
+ self.send_be_disconnect(response=d)
+
+ def send_be_disconnect(self, response=None):
+ msg = packMsg('netif_be_disconnect_t',
+ { 'domid' : self.controller.dom,
+ 'netif_handle' : self.vif })
+ self.getBackendController().writeRequest(msg, response=response)
+
+ def send_be_destroy(self, response=None):
+ msg = packMsg('netif_be_destroy_t',
+ { 'domid' : self.controller.dom,
+ 'netif_handle' : self.vif })
+ self.controller.delDevice(self.vif)
+ self.getBackendController().writeRequest(msg, response=response)
+
+ def recv_fe_interface_connect(self, val, req):
+ if not req: return
+ self.evtchn = channel.eventChannel(0, self.controller.dom)
+ msg = packMsg('netif_be_connect_t',
+ { 'domid' : self.controller.dom,
+ 'netif_handle' : self.vif,
+ 'evtchn' : self.evtchn['port1'],
+ 'tx_shmem_frame' : val['tx_shmem_frame'],
+ 'rx_shmem_frame' : val['rx_shmem_frame'] })
+ d = defer.Deferred()
+ d.addCallback(self.respond_be_connect)
+ self.getBackendController().writeRequest(msg, response=d)
+ def respond_be_connect(self, msg):
+ val = unpackMsg('netif_be_connect_t', msg)
+ dom = val['domid']
+ vif = val['netif_handle']
+ print 'respond_be_connect>', ' dom=', dom, ' vif=', vif
+ print 'respond_be_connect>', 'self.dom=', self.controller.dom, 'self.vif=', self.vif
+ msg = packMsg('netif_fe_interface_status_changed_t',
+ { 'handle' : self.vif,
+ 'status' : NETIF_INTERFACE_STATUS_CONNECTED,
+ 'evtchn' : self.evtchn['port2'],
+ 'mac' : self.mac })
+ self.controller.writeRequest(msg)
+ def attach_fe_device(self):
+ msg = packMsg('netif_fe_interface_status_changed_t',
+ { 'handle' : self.vif,
+ 'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
+ 'evtchn' : 0,
+ 'mac' : self.mac })
+ self.controller.writeRequest(msg)
+
class NetifController(controller.SplitController):
"""Network interface controller. Handles all network devices for a domain.
"""
self.devices[vif] = dev
return dev
+ def delDevice(self, vif):
+ if vif in self.devices:
+ del self.devices[vif]
+
def destroy(self):
"""Destroy the controller and all devices.
"""
@param recreate: recreate flag (true after xend restart)
@return: deferred
"""
- self.addDevice(vif, config)
+ dev = self.addDevice(vif, config)
d = defer.Deferred()
if recreate:
d.callback(self)
else:
- self.send_be_create(vif, response=d)
+ dev.attach(d)
return d
- def reattach_devices(self):
- """Reattach all devices when the back-end control domain has changed.
- """
- self.send_be_create(vif)
- self.attach_fe_devices()
-
- def attach_fe_devices(self):
- for dev in self.devices.values():
- msg = packMsg('netif_fe_interface_status_changed_t',
- { 'handle' : dev.vif,
- 'status' : NETIF_INTERFACE_STATUS_DISCONNECTED,
- 'evtchn' : 0,
- 'mac' : dev.mac })
- self.writeRequest(msg)
-
def recv_fe_driver_status_changed(self, msg, req):
if not req: return
msg = packMsg('netif_fe_driver_status_changed_t',
{ 'status' : NETIF_DRIVER_STATUS_UP,
'nr_interfaces' : len(self.devices) })
self.writeRequest(msg)
- self.attach_fe_devices()
-
+ for dev in self.devices.values():
+ dev.attach_fe_device()
+
def recv_fe_interface_connect(self, msg, req):
val = unpackMsg('netif_fe_interface_connect_t', msg)
- dev = self.devices[val['handle']]
- dev.evtchn = channel.eventChannel(0, self.dom)
- msg = packMsg('netif_be_connect_t',
- { 'domid' : self.dom,
- 'netif_handle' : dev.vif,
- 'evtchn' : dev.evtchn['port1'],
- 'tx_shmem_frame' : val['tx_shmem_frame'],
- 'rx_shmem_frame' : val['rx_shmem_frame'] })
- d = defer.Deferred()
- d.addCallback(self.backendController.respond_be_connect)
- self.backendController.writeRequest(msg, response=d)
-
- def send_interface_connected(self, vif, response=None):
- dev = self.devices[vif]
- msg = packMsg('netif_fe_interface_status_changed_t',
- { 'handle' : dev.vif,
- 'status' : NETIF_INTERFACE_STATUS_CONNECTED,
- 'evtchn' : dev.evtchn['port2'],
- 'mac' : dev.mac })
- self.writeRequest(msg, response=response)
-
- def send_be_create(self, vif, response=None):
- dev = self.devices[vif]
- msg = packMsg('netif_be_create_t',
- { 'domid' : self.dom,
- 'netif_handle' : dev.vif,
- 'mac' : dev.mac })
- self.backendController.writeRequest(msg, response=response)
-
- def send_be_disconnect(self, vif, response=None):
- dev = self.devices[vif]
- msg = packMsg('netif_be_disconnect_t',
- { 'domid' : self.dom,
- 'netif_handle' : dev.vif })
- self.backendController.writeRequest(msg, response=response)
+ vif = val['handle']
+ dev = self.devices.get(vif)
+ if dev:
+ dev.recv_fe_interface_connect(val, req)
+ else:
+ log.error('Received netif_fe_interface_connect for unknown vif: '+vif)
- def send_be_destroy(self, vif, response=None):
- dev = self.devices[vif]
- del self.devices[vif]
- msg = packMsg('netif_be_destroy_t',
- { 'domid' : self.dom,
- 'netif_handle' : vif })
- self.backendController.writeRequest(msg, response=response)